/* ==================================================================
* Copyright (c) 2024/11/15 SCNU LiuJunJie z-ken
* All rights reserved.
* fileName:	NfaDfaRecord.hpp
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the xxx Group. and
* its contributors.
* 4. Neither the name of the Group nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Author,GROUP AND CONTRIBUTORS
* ===================================================================
* Author: LiuJunJie z-ken.
*/

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include "Base.hpp"
#include "reToNFA.hpp"
#include "NFAToDFA.hpp"
using namespace std;

#if !defined(NFA_DFA_RECORD)
#define NFA_DFA_RECORD
class NfaDfaRecordUtil
{
public:
    static string vectorToString(vector<int> t)
    {
        string res = "{";
        for (auto p : t)
        {
            res += to_string(p) + ",";
        }
        res += "}";
        return res;
    }
};

class NfaRecord
{
public:
    vector<vector<vector<int>>> NFA;
    int NFA2_node_number;
    int baseLength;
    vector<Base> resualt; // 记录所有的加入的基本re

    // 起点和终点
    int nfa_start;
    int nfa_end;
    // 标识信息
    string reTokenName;
    // 参数
    int isShow = 0;

    NfaRecord() {}
    NfaRecord(vector<vector<vector<int>>> NFA, int NFA2_node_number,
              int baseLength, vector<Base> resualt)
    {
        this->NFA = NFA;
        this->NFA2_node_number = NFA2_node_number;
        this->baseLength = baseLength;
        this->resualt = resualt;
    }
    // show函数
    void showNFA2()
    {
        if (isShow == 0)
        {
            return;
        }
        // 保存默认的输出格式
        ios_base::fmtflags defaultFlags = cout.flags();
        streamsize defaultWidth = cout.width();
        cout << "NFA2的内容" << endl;

        cout << left;
        cout << setw(M_OUTPUT_LEN) << "re:";
        for (int i = 0; i <= baseLength; i++)
        {
            cout << setw(M_OUTPUT_LEN) << to_string(i) + ":" + resualt[i].regular_Expression;
        }
        cout << endl;

        for (int i = 1; i < NFA2_node_number; i++)
        {
            cout << setw(M_OUTPUT_LEN) << "row:" + to_string(i) + ":";
            for (int j = 0; j <= baseLength; j++)
            {
                cout << setw(M_OUTPUT_LEN) << NfaDfaRecordUtil::vectorToString(NFA[i][j]);
            }
            cout << endl;
        }

        // 恢复默认的输出格式
        cout.flags(defaultFlags);
        cout.width(defaultWidth);
        //
    }
};

class DfaRecord
{
public:
    vector<Base> baseState;               // 记录所有的加入的基本re
    map<int, map<string, int>> state_DFA; // 集合变化为状态的DFA
    set<int> startState;                  // 变换为状态DFA后，分类为终点state和起点state
    set<int> endState;                    // 变换为状态DFA后，分类为终点state和起点state


    // 参数
    int isShow = 0; // 如果为1，调用showStateDFA的时候会进行打印

    DfaRecord() {}
    DfaRecord(vector<Base> baseState, map<int, map<string, int>> state_DFA, set<int> startState, set<int> endState)
    {
        this->baseState = baseState;
        this->state_DFA = state_DFA;
        this->startState = startState;
        this->endState = endState;
    }

    void showStateDFA()
    {
        cout << "展示DFA的StateDFA" << endl;

        cout << "self:";
        // baseState默认一号位置是# 空符号，可以省略不输出
        for (int i = 1; i < baseState.size(); i++)
        {
            cout << '\t' << to_string(i) + ":" + baseState[i].regular_Expression;
        }
        cout << endl;
        for (auto p : state_DFA)
        {
            cout << p.first << "\t";
            // baseState默认一号位置是# 空符号，可以省略不输出
            for (int i = 1; i < baseState.size(); i++)
            {
                // 获取一个可能走的边
                string re_tmp = baseState[i].regular_Expression;
                cout << p.second[re_tmp] << "\t";
            }
            cout << endl;
        }
    }
};

class NfaDfaRecord
{
public:
    // vector<vector<vector<int>>>是NFA的数据类型
    vector<NfaRecord> NFA_s_record;
    // 状态DFA的记录，有最小化的DFA和未最小化的DFA
    // 基础数据类型 map<int, map<string, int>> state_DFA;     // 集合变化为状态的DFA
    // 基础数据类型 map<int, map<string, int>> state_min_DFA; // 集合变化为状态的DFA
    vector<DfaRecord> stateDFA_s;
    vector<DfaRecord> minStateDFA_s;

    /**
     * 加入一个记录内容
     */
    void addNFA(const reToNFA &re)
    {
        NfaRecord record(re.NFA2, re.NFA2_node_number, re.baseLength, re.resualt);
        record.reTokenName = re.tokenName;
        record.nfa_start = re.nfa2_start;
        record.nfa_end = re.nfa2_end;
        NFA_s_record.push_back(record);
    }
    /**
     * 加入最小化的状态DFA
     */
    void addMinStateDfa(const DFA_Builder &dfaBuilder)
    {
        DfaRecord record(dfaBuilder.baseState, dfaBuilder.state_min_DFA, dfaBuilder.startState, dfaBuilder.endState);
        minStateDFA_s.push_back(record);
        // record.isShow = 1;
        // record.showStateDFA();
    }
    /**
     * 加入未最小化的状态DFA
     */
    void addStateDfa(const DFA_Builder &dfaBuilder)
    {
        DfaRecord record(dfaBuilder.baseState, dfaBuilder.state_DFA, dfaBuilder.startState, dfaBuilder.endState);
        stateDFA_s.push_back(record);
        // record.isShow = 1;
        // record.showStateDFA();
    }
};

#endif // NFA_DFA_RECORD
